package com.guodi.map.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.BeanUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.guodi.common.constant.StatusCode;
import com.guodi.common.utils.UuidUtil;
import com.guodi.core.boot.ctrl.BaseController;
import com.guodi.core.tool.api.R;
import com.guodi.core.tool.utils.Func;
import com.guodi.map.entity.*;
import com.guodi.map.service.*;
import com.guodi.map.utils.RecursionUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import java.util.*;


/**
 * @描述：专题图层认证表控制类
 * @作者: 代鹏刚
 * @日期: 2020-01-14
 */
@RestController
@RequestMapping("/MapProjectAuth")
@Api(value = "API - MapProjectAuthController", tags = "专题图层认证表")
public class MapProjectAuthController extends BaseController {

    @Autowired
    private IMapProjectAuthService mapProjectAuthService;
    @Autowired
    private IMapProjectService mapProjectService;
    @Autowired
    private IMapProjectDirService mapProjectDirService;
    @Autowired
    private IMapParamService mapParamService;
    @Autowired
    private IMapLayerCollectService iMapLayerCollectService;
    @Autowired
    private IMapLayerService layerService;
    @Autowired
    private IMapSceneService iMapSceneService;

    /**
    * @描述: 根据实体属性分页查询
    * @入参:
    * @出参:
    * @作者: 代鹏刚
    * @日期: 2020-01-14
    **/
    @PostMapping("/listByEntity")
    @ApiOperation(value = " 根据实体属性分页查询")
    public R listByEntity(Page page, MapProjectAuth mapProjectAuth){
        LambdaQueryWrapper<MapProjectAuth> wrapper = new QueryWrapper().lambda();
        IPage<MapProjectAuth> iPage = mapProjectAuthService.page(page, wrapper);
        return R.data(iPage);
    }

    /**
     * @描述: 根据主键查询
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2020-01-14
     **/
    @PostMapping("/findById")
    @ApiOperation(value = "根据主键查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true,
                    dataType = "string", paramType = "query")
    })
    public R findById(String id) {
        if(StringUtils.isBlank(id)){
            return R.fail(StatusCode.ERROR_CODE_40005,"id不能为空");
        }
        MapProjectAuth mapProjectAuth = mapProjectAuthService.getById(id);
        return R.data(mapProjectAuth);
    }

    /**
     * @描述: 授权
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2020-01-14
     **/
    @PostMapping("/save")
    @ApiOperation(value = "授权")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "projectId", value = "专题集ID", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "projectDirIds", value = "专题ID", allowMultiple = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "orgIds", value = "当前专题目录所属组织机构集合", allowMultiple = true, dataType = "string", paramType = "query")
    })
    public R save(String roleId, String projectId, String[] projectDirIds, String[] orgIds){
        //授权前，删除先前的数据
        mapProjectAuthService.removeByMaps(roleId,projectId,orgIds);
        if(null != projectDirIds && projectDirIds.length > 0){
            List<MapProjectAuth> list = new ArrayList<>();
            for (String id:projectDirIds) {
                MapProjectAuth mapProjectAuth = new MapProjectAuth();
                mapProjectAuth.setId(UuidUtil.get32UUID());
                mapProjectAuth.setRoleId(roleId);
                mapProjectAuth.setProjectDirId(id);
                mapProjectAuth.setProjectId(projectId);
                prepareData(mapProjectAuth, true);
                list.add(mapProjectAuth);
            }
            mapProjectAuthService.saveBatch(list);
        }
        return R.data(null);
    }

    /**
    * @描述: 根据roleId获取已授权专题
    * @入参:
    * @出参:
    * @作者: 代鹏刚
    * @日期: 2020/1/14 14:44
    **/
    @PostMapping("/getProjectByRoleIds")
    @ApiOperation(value = "根据roleId获取已授权专题")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleIds", value = "roleId", allowMultiple = true, required = true, dataType = "string", paramType = "query")
    })
    public R getProjectByRoleIds(String[] roleIds){
        List<MapProjectAuth> list = mapProjectAuthService.getProjectByRoleIds(roleIds);
        return R.data(list);
    }

    /**
     * @描述: 修改
     * @入参:
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2020-01-14
     **/
    @PostMapping("/update")
    @ApiOperation(value = "修改")
    public R update(MapProjectAuth mapProjectAuth) {
        prepareData(mapProjectAuth, false);
        mapProjectAuthService.updateById(mapProjectAuth);
        return R.data(mapProjectAuth);
    }

    /**
     * @描述: 根据主键删除
     * @入参: id
     * @出参:
     * @作者: 代鹏刚
     * @日期: 2020-01-14
     **/
    @PostMapping("/delete")
    @ApiOperation(value = "根据主键删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true,
                    dataType = "string", paramType = "query")
    })
    public R delete(String id){
        return R.status(mapProjectAuthService.removeById(id));
    }

    /**
    * @描述: 业务系统获取已授权的专题集
    * @入参:
    * @出参:
    * @作者: 代鹏刚
    * @日期: 2020/2/18 14:38
    **/
    @PostMapping("/getSpecialSet")
    @ApiOperation(value = "业务系统获取已授权的专题集")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页码", required = true, dataType = "long", paramType = "query", example = "1"),
            @ApiImplicitParam(name = "size", value = "每页显示数量", required = true, dataType = "long", paramType = "query", example = "10")
    })
    public R getSpecialSet(@ApiIgnore Page page){
        if(null == getUser().getRoleId()){
            return R.fail(StatusCode.ERROR_CODE_40005,"当前用户角色为空，请检查！");
        }
        List<MapProjectAuth> mapProjectAuths = mapProjectAuthService.getSpecialSet(page, Func.toStrList(getUser().getRoleId()));
        page.setRecords(mapProjectAuths);
        page.setTotal(page.getTotal());
        return R.data(page);
    }

    /**
    * @描述: 业务系统获取已授权的专题目录
    * @入参:
    * @出参:
    * @作者: 代鹏刚
    * @日期: 2020/2/19 14:55
    **/
    @PostMapping("/getSpecialMenu")
    @ApiOperation(value = "业务系统获取已授权的专题目录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectId", value = "专题集ID", required = true, dataType = "string", paramType = "query")
    })
    public R getSpecialMenu(String projectId){
        if(null == getUser().getRoleId()){
            return R.fail(StatusCode.ERROR_CODE_40005,"当前用户角色为空，请检查！");
        }
        List<MapProjectDir> mapProjectDirs = mapProjectDirService.getSpecialMenu(Func.toStrList(getUser().getRoleId()),projectId,null,null);
        return R.data(RecursionUtil.buildProjectDirTree(mapProjectDirs));
    }

    /**
    * @描述: 获取授权专题中底图数据
    * @入参:
    * @出参:
    * @作者: 代鹏刚
    * @日期: 2020/2/28 11:39
    **/
    @PostMapping("/getSpecialBaseMap")
    @ApiOperation(value = "获取授权专题中底图数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectId", value = "专题集ID", required = true, dataType = "string", paramType = "query")
    })
    public R getSpecialBaseMap(String projectId){
        if(null == getUser().getRoleId()){
            return R.fail(StatusCode.ERROR_CODE_40005,"当前用户角色为空，请检查！");
        }
        List<MapProjectDir> mapProjectDirs = mapProjectDirService.getSpecialMenu(Func.toStrList(getUser().getRoleId()),projectId,null,"6");
        return R.data(mapProjectDirs);
    }

    /**
    * @描述: 根据projectCode获取已授权的专题目录树与地图参数
    * @入参:
    * @出参:
    * @作者: 代鹏刚
    * @日期: 2020/3/22 14:34
    **/
    @PostMapping("/getDataByProjectCode")
    @ApiOperation(value = "根据projectCode获取已授权的专题目录树与地图参数")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectCode", value = "专题集编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "当前用户关联行政区划代码", required = true, dataType = "string", paramType = "query")
    })
    public R getDataByProjectCode(String projectCode, String divisionCode){
        if (StringUtils.isBlank(divisionCode)) {
            return R.fail(StatusCode.ERROR_CODE_40005,"请在GIS运维行政区划管理配置当前用户机构关联的行政区划");
        }
        if(null == getUser().getRoleId()){
            return R.fail("");
        }
        Map<String, Object> map = new HashMap<>();
        List<String> roleIds = Func.toStrList(getUser().getRoleId());
        List<MapProjectDir> mapProjectDirs = mapProjectDirService.getSpecialMenu(roleIds,null,projectCode,null);
        mapProjectDirs = getChildLayer(mapProjectDirs);
        String projectId="";
        if(mapProjectDirs!=null&&!mapProjectDirs.isEmpty()){
            projectId = mapProjectDirs.get(0).getProjectId();
        }
        // 收藏列表
        List<MapProjectDir> mapCollectProjects = iMapLayerCollectService.listUserCollectLayers(getUser(),projectId);
        // 添加是否收藏字段
        for (MapProjectDir mapProjectDir : mapProjectDirs) {
            // 只有图层目录和图层，才设置收藏字段
            if (mapProjectDir.getType() == 2 || mapProjectDir.getIsLayerDir() == 1){
                boolean present = mapCollectProjects.stream().filter(dir -> {
                    return mapProjectDir.getId().equalsIgnoreCase(dir.getId());
                }).findAny().isPresent();
                mapProjectDir.setIsCollect(present == true? 1:0);
            }
        }
        // 存储临时变量，返回常用目录树、收藏图层
        List<MapProjectDir> mapCollects = new ArrayList<>(mapProjectDirs);
        MapParam mapParams = mapParamService.findByProjectCode(projectCode, divisionCode);

        //获取专题关联的场景配置
        //场景配置id
        String paramId = null;
        MapScene mapScene = null;
        LambdaQueryWrapper<MapProject> lambdaQueryWrapper = new QueryWrapper().lambda();
        lambdaQueryWrapper.eq(MapProject::getCode,projectCode);
        MapProject mapProject = mapProjectService.getOne(lambdaQueryWrapper);
        if(StringUtils.isNotBlank(mapProject.getParamId())){
            paramId = mapProject.getParamId();
            mapScene = iMapSceneService.getById(paramId);
        }

        // 全局目录
        map.put("mapProjectDirs", BeanUtils.beansToMaps(RecursionUtil.buildProjectDirTree(mapProjectDirs)));
        // 图层参数
        map.put("mapParams",mapParams);
        // 常用目录
        map.put("mapAppointDirs", RecursionUtil.buildAppointTree(mapCollects));
        // 收藏目录
        map.put("mapCollects", mapCollectProjects);
        // 场景专题配置
        map.put("mapScene",mapScene);
        return  R.data(map);
    }


    /**
    * @描述: 补充服务的图层id
    * @入参:
    * @出参:
    * @作者: 代鹏刚
    * @日期: 2022/4/28 17:21
    **/
    private List<MapProjectDir> getChildLayer(List<MapProjectDir> mapProjectDirs){
        if(mapProjectDirs==null||mapProjectDirs.isEmpty()){
            return mapProjectDirs;
        }
        List<MapProjectDir> result =new ArrayList<>();
        Map<String,List<MapProjectDir>> serviceList =new HashMap<>();
        Set<String> layerIds = new HashSet<>();
        for (MapProjectDir mapProjectDir : mapProjectDirs) {
            MapLayer mapLayer = mapProjectDir.getMapLayer();
            if(StringUtils.isBlank(mapLayer.getMid())){
                mapLayer.setType(null);
//                mapProjectDir.setMapLayer(null);
            }
            if(mapLayer!=null&&"-1".equals(mapLayer.getLayerTable())){
                String mid = mapLayer.getMid();
                List<MapProjectDir> serviceProjectDirs = serviceList.get(mid);
                if(serviceProjectDirs==null){
                    serviceProjectDirs = new ArrayList<>();
                }
                layerIds.add(mid);
                serviceProjectDirs.add(mapProjectDir);
                serviceList.put(mid,serviceProjectDirs);
            }else{

                result.add(mapProjectDir);
            }
        }
        Map<String,StringBuilder> childLayerList =new HashMap<>();
        if(!layerIds.isEmpty()){
            LambdaQueryWrapper<MapLayer> wrapper = Wrappers.lambdaQuery();
            wrapper.in(MapLayer::getParentId,layerIds);
            List<MapLayer> mapLayers = layerService.list(wrapper);
            if(mapLayers!=null&&!mapLayers.isEmpty()){
                for (MapLayer mapLayer : mapLayers) {
                    String parentId = mapLayer.getParentId();
                    StringBuilder childLayers = childLayerList.get(parentId);
                    if(childLayers==null){
                        childLayers= new StringBuilder();
                    }
                    childLayers.append(mapLayer.getLayerTable()+",");
                    childLayerList.put(parentId,childLayers);
                }
            }
        }
        for (Map.Entry<String,StringBuilder> entry:childLayerList.entrySet()){
            StringBuilder value = entry.getValue();
            childLayerList.put(entry.getKey(),value.deleteCharAt(value.length()-1));
        }
        for (Map.Entry<String,List<MapProjectDir>> entry:serviceList.entrySet()){
            List<MapProjectDir> value = entry.getValue();
            StringBuilder stringBuilder = childLayerList.get(entry.getKey());
            if(stringBuilder!=null&&stringBuilder.length()>0){
                for (MapProjectDir mapProjectDir : value) {
                    MapLayer mapLayer = mapProjectDir.getMapLayer();
                    mapLayer.setLayerTable(stringBuilder.toString());
                }
            }
            result.addAll(value);
        }

        return result;
    }

    /**
     * @作者: 林楷 2021/5/25
     * @描述: 根据projectCode获取已授权的专题目录列表（默认返回一级目录列表）与地图参数
     * @参数: null
     * @返回: null
     */
    @PostMapping("/getDataByProjectCodeLazyLoad")
    @ApiOperation(value = "根据projectCode获取已授权的专题目录树与地图参数")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectCode", value = "专题集编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "divisionCode", value = "当前用户关联行政区划代码", required = true, dataType = "string", paramType = "query")
    })
    public R getDataByProjectCodeLazyLoad(String projectCode, String divisionCode){
        if(null == getUser().getRoleId()){
            return R.fail(StatusCode.ERROR_CODE_40005,"当前用户角色为空，请检查！");
        }
        Map<String, Object> map = new HashMap<>();
        List<String> roleIds = Func.toStrList(getUser().getRoleId());
        List<MapProjectDir> mapProjectDirs = mapProjectDirService.getSpecialMenuByParentId(roleIds,null,projectCode,null,"-1");
        // 收藏列表
        List<MapProjectDir> mapCollectProjects = iMapLayerCollectService.listUserCollectLayers(getUser(),null);
        // 添加是否收藏字段
        for (MapProjectDir mapProjectDir : mapProjectDirs) {
            // 只有图层目录和图层，才设置收藏字段
            if (mapProjectDir.getType() == 2 || mapProjectDir.getIsLayerDir() == 1){
                boolean present = mapCollectProjects.stream().filter(dir -> {
                    return mapProjectDir.getId().equalsIgnoreCase(dir.getId());
                }).findAny().isPresent();
                mapProjectDir.setIsCollect(present == true? 1:0);
            }
        }
        // 存储临时变量，返回常用目录树、收藏图层
        List<MapProjectDir> mapCollects = new ArrayList<>(mapProjectDirs);
        // 处理多组织问题，默认取第一个
        MapParam mapParams = mapParamService.findByProjectCode(projectCode, divisionCode);
        // 全局目录
        map.put("mapProjectDirs", RecursionUtil.buildProjectDirTree(mapProjectDirs));
        // 图层参数
        map.put("mapParams",mapParams);
        // 常用目录
        map.put("mapAppointDirs", RecursionUtil.buildAppointTree(mapCollects));
        // 收藏目录
        map.put("mapCollects", mapCollectProjects);
        return  R.data(map);
    }
    /**
     * @作者: 林楷 2021/5/25
     * @描述: 根据projectCode,parentId获取已授权的专题目录列表
     * @参数: null
     * @返回: null
     */
    @PostMapping("/lazyLoadDataByProjectCodeAndParentId")
    @ApiOperation(value = "根据projectCode,parentId获取已授权的专题目录列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "projectCode", value = "专题集编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "parentId", value = "父级ID，默认给-1", required = true, dataType = "string", paramType = "query")
    })
    public R lazyLoadDataByProjectCodeAndParentId(String projectCode, String parentId){
        if(null == getUser().getRoleId()){
            return R.fail(StatusCode.ERROR_CODE_40005,"当前用户角色为空，请检查！");
        }
        List<String> roleIds = Func.toStrList(getUser().getRoleId());
        List<MapProjectDir> mapProjectDirs = mapProjectDirService.getSpecialMenuByParentId(roleIds,null,projectCode,null,parentId);
        // 收藏列表
        List<MapProjectDir> mapCollectProjects = iMapLayerCollectService.listUserCollectLayers(getUser(),null);
        // 添加是否收藏字段
        for (MapProjectDir mapProjectDir : mapProjectDirs) {
            // 只有图层目录和图层，才设置收藏字段
            if (mapProjectDir.getType() == 2 || mapProjectDir.getIsLayerDir() == 1){
                boolean present = mapCollectProjects.stream().filter(dir -> {
                    return mapProjectDir.getId().equalsIgnoreCase(dir.getId());
                }).findAny().isPresent();
                mapProjectDir.setIsCollect(present == true? 1:0);
            }
        }
        return  R.data(mapProjectDirs);
    }
    private void prepareData(MapProjectAuth mapProjectAuth, boolean isSave) {
        if(isSave){
            mapProjectAuth.setCreator(getUser().getUserId().toString());
            mapProjectAuth.setCreateTime(new Date());
            //防止误修改
            mapProjectAuth.setModifier(null);
            mapProjectAuth.setModifyTime(null);
        }else{
            mapProjectAuth.setModifier(getUser().getUserId().toString());
            mapProjectAuth.setModifyTime(new Date());
            //防止误修改
            mapProjectAuth.setCreator(null);
            mapProjectAuth.setCreateTime(null);
        }
    }
}
